home *** CD-ROM | disk | FTP | other *** search
/ Hobby PC 15 / Hobby PC 15.iso / Soft / Blender / blender.exe / ic255.cab / python / lwoimport.py < prev    next >
Text File  |  2001-03-15  |  11KB  |  330 lines

  1. #######################
  2. # (c) Jan Walter 2000 #
  3. #######################
  4.  
  5. # CVS
  6. # $Author: jan $
  7. # $Date: 2001/02/02 15:48:53 $
  8. # $RCSfile: lwoimport.py,v $
  9. # $Revision: 1.4 $
  10.  
  11. # why not use the chunk module ???
  12.  
  13. import string
  14. import struct
  15. import Blender
  16.  
  17. LWOscale = 10
  18.  
  19. def readChunk(file):
  20.     tag = file.read(4)
  21.     data = struct.unpack(">L", file.read(4)) # big endian
  22.     length = data[0]
  23.     return tag, length
  24.  
  25. def readFace(file):
  26.     bytes = 0
  27.     numvert = struct.unpack(">H", file.read(2)) # numvert
  28.     bytes = bytes + 2
  29.     numvert = numvert[0]
  30.     verts = []
  31.     for index in xrange(numvert):
  32.         vert = struct.unpack(">H", file.read(2)) # vert
  33.         bytes = bytes + 2
  34.         verts.append(vert[0])
  35.     surf = struct.unpack(">h", file.read(2)) # surf
  36.     bytes = bytes + 2
  37.     surf = surf[0]
  38.     face = numvert, verts, surf
  39.     return face, bytes
  40.  
  41. def readFaceList(file, length):
  42.     faceList = []
  43.     numFaces = 0
  44.     bytes = 0
  45.     while bytes < length:
  46.         face, numBytes = readFace(file)
  47.         bytes = bytes + numBytes
  48.         faceList.append(face)
  49.     print "numFaces:", len(faceList)
  50.     return faceList
  51.  
  52. def readPoint(file):
  53.     return struct.unpack(">3f", file.read(12)) # big endian
  54.  
  55. def readPointList(file, length):
  56.     pointList = []
  57.     numPoints = length / 12
  58.     print "numPoints:", numPoints
  59.     for index in xrange(numPoints):
  60.         point = readPoint(file)
  61.         pointList.append(point)
  62.     return pointList
  63.  
  64. def readSurfaceDefinition(file, length):
  65.     surfaceDefinition = []
  66.     bytes = file.read(length)
  67.     words = string.split(bytes, '\0')
  68.     bytes = bytes[(len(words[0])+1):]
  69.     # skip \0
  70.     while bytes[0] == '\0':
  71.         bytes = bytes[1:]
  72.     while bytes != '':
  73.         subChunk, bytes = readSurfaceSubChunk(bytes)
  74.         surfaceDefinition.append(subChunk)
  75.     return surfaceDefinition
  76.  
  77. def readSurfaceSubChunk(bytes):
  78.     subChunk = []
  79.     tag = bytes[:4]
  80.     bytes = bytes[4:]
  81.     data = struct.unpack(">H", bytes[:2])
  82.     bytes = bytes[2:]
  83.     length = data[0]
  84.     if tag in ["COLR", "TCLR"]:
  85.         subChunk.append(tag)
  86.         r, g, b, pad = struct.unpack(">4B", bytes[:4])
  87.         bytes = bytes[4:]
  88.         subChunk.append((r, g, b))
  89.     elif tag in ["FLAG", "RFLT", "TFLG", "TFRQ"]:
  90.         subChunk.append(tag)
  91.         value = struct.unpack(">H", bytes[:2])
  92.         value = value[0]
  93.         bytes = bytes[2:]
  94.         subChunk.append(value)
  95.     elif (tag in ["LUMI", "DIFF", "SPEC", "REFL", "TRAN", "GLOS", "TVAL"] or
  96.           tag[:3] == "TIP"):
  97.         subChunk.append(tag)
  98.         value = struct.unpack(">h", bytes[:2])
  99.         value = value[0]
  100.         bytes = bytes[2:]
  101.         subChunk.append(value)
  102.     elif (tag in ["VLUM", "VDIF", "VSPC", "VRFL", "VTRN", "RSAN", "RIND",
  103.                   "EDGE", "SMAN", "TAMP", "TAAS", "TOPC"] or
  104.           tag[:3] == "TFP" or tag[:3] == "TSP"):
  105.         subChunk.append(tag)
  106.         value = struct.unpack(">f", bytes[:4])
  107.         value = value[0]
  108.         bytes = bytes[4:]
  109.         subChunk.append(value)
  110.     elif tag in ["RIMG", "CTEX", "DTEX", "STEX", "RTEX", "TTEX", "LTEX",
  111.                  "BTEX", "TIMG", "TALP"]:
  112.         subChunk.append(tag)
  113.         words = string.split(bytes, '\0')
  114.         filename = words[0]
  115.         bytes = bytes[(len(words[0])+1):]
  116.         # skip \0
  117.         while bytes[0] == '\0':
  118.             bytes = bytes[1:]
  119.         subChunk.append(filename)
  120.     elif tag in ["TSIZ", "TCTR", "TFAL", "TVEL"]:
  121.         subChunk.append(tag)
  122.         values = struct.unpack(">3f", bytes[:12]) # big endian
  123.         bytes = bytes[12:]
  124.         subChunk.append(values)
  125.     elif tag == "TWRP":
  126.         subChunk.append(tag)
  127.         values = struct.unpack(">HH", bytes[:4])
  128.         bytes = bytes[4:]
  129.         subChunk.append(values)
  130.     else:
  131.         bytes = bytes[length:]
  132.     return subChunk, bytes
  133.  
  134. def readSurfaceList(file, length):
  135.     bytes = file.read(length)
  136.     words = string.split(bytes, '\0')
  137.     surfaceList = []
  138.     for word in words:
  139.         if word:
  140.             surfaceList.append(word)
  141.     return surfaceList
  142.  
  143. def checkForOneLoop(indices):
  144.     for i in xrange(len(indices) - 1):
  145.         if indices.count(indices[i]) > 1:
  146.             return 0
  147. ##         if indices[i] in (indices[0:i] + indices[(i+1):]):
  148. ##             return 0
  149.     return 1
  150.  
  151. def testLwoImport(filename):
  152.     global LWOscale
  153.     
  154.     print 'testLwoImport("%s")' % filename
  155.     file = open(filename, "rb")
  156.     tag, length = readChunk(file)
  157.     if tag == "FORM":
  158.         lwob = file.read(4)
  159.         if lwob == "LWOB":
  160.             print '"LightWave 3D Object File Format" found'
  161.             filelength = length
  162.             numBytes = 4
  163.             while (numBytes < filelength):
  164.                 tag, length = readChunk(file)
  165.                 numBytes = numBytes + 8
  166.                 if length % 2 != 0:
  167.                     length = length + 1
  168.                 # surface list
  169.                 if tag == "SRFS":
  170.                     surfaceList = readSurfaceList(file, length)
  171.                 # point list
  172.                 elif tag == "PNTS":
  173.                     pointList = readPointList(file, length)
  174.                 # face list
  175.                 elif tag == "POLS":
  176.                     faceList = readFaceList(file, length)
  177.                 # surface definition
  178.                 elif tag == "SURF":
  179.                     surfaceDefinition = readSurfaceDefinition(file, length)
  180.                 else:
  181.                     file.read(length)
  182.                 numBytes = numBytes + length
  183.         else:
  184.             print 'No "LightWave 3D Object File Format" found :-['
  185.             return
  186.     file.close()
  187.     # import in Blender
  188.     print "import into Blender ..."
  189.     scene  = Blender.getCurrentScene()
  190.     print "triangles and quads ..."
  191.     for materialIndex in xrange(1, len(surfaceList) + 1):
  192.         mesh   = Blender.Mesh("LWO")
  193.         object = Blender.Object("LWO")
  194.         for face in faceList:
  195.             numvert, vert, surf = face
  196.             if surf == materialIndex:
  197.                 if numvert == 3:
  198.                     # triangle
  199.                     mesh.enterEditMode()
  200.                     indices = []
  201.                     for vertex in vert:
  202.                         x, y, z = pointList[vertex]
  203.                         x = x * LWOscale
  204.                         y = y * LWOscale
  205.                         z = z * LWOscale
  206.                         index = mesh.addVertex(x, y, z, 0, 0, 0)
  207.                         indices.append(index)
  208.                     mesh.addFace(indices[0], indices[1], indices[2], 0, 0, 0)
  209.                 elif numvert == 4:
  210.                     # quad
  211.                     mesh.enterEditMode()
  212.                     indices = []
  213.                     for vertex in vert:
  214.                         x, y, z = pointList[vertex]
  215.                         x = x * LWOscale
  216.                         y = y * LWOscale
  217.                         z = z * LWOscale
  218.                         index = mesh.addVertex(x, y, z, 0, 0, 0)
  219.                         indices.append(index)
  220.                     mesh.addFace(indices[0], indices[1],
  221.                                  indices[2], indices[3], 0, 0)
  222.         Blender.connect(object, mesh)
  223.         Blender.connect(scene, object)
  224.         mesh.leaveEditMode()
  225.     print "all other (general) polygons ..."
  226.     for face in faceList:
  227.         numvert, vert, surf = face
  228.         # one polygon
  229.         if numvert != 3 and numvert != 4:
  230.             mesh   = Blender.Mesh("LWO")
  231.             object = Blender.Object("LWO")
  232.             hasOneLoop = checkForOneLoop(vert)
  233.             mesh.enterEditMode()
  234.             for i in xrange(len(vert)-1):
  235.                 if vert.count(vert[i]) == 2:
  236.                     first = vert.index(vert[i])
  237.                     remaining = vert[0:first] + vert[(first+1):]
  238.                     second = remaining.index(vert[i]) + 1
  239.                     if i == first and vert[first+1] == vert[second-1]:
  240.                         # print "ignore first edge"
  241.                         pass
  242.                     elif i == second and vert[first-1] == vert[second+1]:
  243.                         # print "ignore second edge"
  244.                         pass
  245.                     else:
  246.                         # print "edge not ignored"
  247.                         x, y, z = pointList[vert[i]]
  248.                         x = x * LWOscale
  249.                         y = y * LWOscale
  250.                         z = z * LWOscale
  251.                         index1 = mesh.addVertex(x, y, z, 0, 0, 0)
  252.                         x, y, z = pointList[vert[i+1]]
  253.                         x = x * LWOscale
  254.                         y = y * LWOscale
  255.                         z = z * LWOscale
  256.                         index2 = mesh.addVertex(x, y, z, 0, 0, 0)
  257.                         mesh.addFace(index1, index2, 0, 0, 0, 0)
  258.                 elif vert.count(vert[i]) > 2:
  259.                     print ("vert.count(vert[%s]) = %s" %
  260.                            (i, vert.count(vert[i])))
  261.                 else:
  262.                     x, y, z = pointList[vert[i]]
  263.                     x = x * LWOscale
  264.                     y = y * LWOscale
  265.                     z = z * LWOscale
  266.                     index1 = mesh.addVertex(x, y, z, 0, 0, 0)
  267.                     x, y, z = pointList[vert[i+1]]
  268.                     x = x * LWOscale
  269.                     y = y * LWOscale
  270.                     z = z * LWOscale
  271.                     index2 = mesh.addVertex(x, y, z, 0, 0, 0)
  272.                     mesh.addFace(index1, index2, 0, 0, 0, 0)
  273.             # add edge from last point to the first point to
  274.             # close the polygon
  275.             if vert.count(vert[-1]) == 2:
  276.                 first  = vert.index(vert[-1])
  277.                 second = -1
  278.                 if vert[first-1] == vert[second+1]:
  279.                     # print "ignore second edge"
  280.                     pass
  281.                 else:
  282.                     x, y, z = pointList[vert[0]]
  283.                     x = x * LWOscale
  284.                     y = y * LWOscale
  285.                     z = z * LWOscale
  286.                     index1 = mesh.addVertex(x, y, z, 0, 0, 0)
  287.                     x, y, z = pointList[vert[-1]]
  288.                     x = x * LWOscale
  289.                     y = y * LWOscale
  290.                     z = z * LWOscale
  291.                     index2 = mesh.addVertex(x, y, z, 0, 0, 0)
  292.                     mesh.addFace(index1, index2, 0, 0, 0, 0)
  293.             else:
  294.                 x, y, z = pointList[vert[0]]
  295.                 x = x * LWOscale
  296.                 y = y * LWOscale
  297.                 z = z * LWOscale
  298.                 index1 = mesh.addVertex(x, y, z, 0, 0, 0)
  299.                 x, y, z = pointList[vert[-1]]
  300.                 x = x * LWOscale
  301.                 y = y * LWOscale
  302.                 z = z * LWOscale
  303.                 index2 = mesh.addVertex(x, y, z, 0, 0, 0)
  304.                 mesh.addFace(index1, index2, 0, 0, 0, 0)
  305.             # remove doubles and triangulate
  306.             if hasOneLoop:
  307.                 # polygon without subloops
  308.                 mesh.createTrianglesFromEdges()
  309.             else:
  310.                 # polygon with subloops
  311.                 mesh.createTrianglesFromEdges()
  312.             # now connect ...
  313.             Blender.connect(object, mesh)
  314.             Blender.connect(scene, object)
  315.             mesh.leaveEditMode()
  316.     print "... finished"
  317.         
  318. def callback(fs):
  319.     filename = fs.filename
  320.     testLwoImport(filename)
  321.  
  322. if __name__ == "__main__":
  323.     try:
  324.         import GUI
  325.     except:
  326.         print "This script is only working with the new GUI module ..."
  327.     else:
  328.         fs = GUI.FileSelector()
  329.         fs.activate(callback, fs)
  330.